import * as THREE from 'three'
import {
  pointListToV3,
  generatePoints
} from './utils'

type GeometryModelOptions = {
  /**物体点位数据 */
  points: [number, number][]
  /**物体高度 */
  height?: number
  name?: string
  /**物体颜色 */
  color?: THREE.Color
  /**边线颜色 */
  lineColor?: THREE.Color
}

function createBuilding ({
  points,
  color = new THREE.Color(0xffffff),
  name = '',
  height = 10,
  lineColor = new THREE.Color(0x00ffff),
}: GeometryModelOptions) {
  const pointsVector2 = parsePoints(points)
  const shape = new THREE.Shape(pointsVector2)
  const extrudeSettings = {
    steps: 1,
    depth: 0,
    bevelEnabled: true,
    bevelThickness: height / 2,
    bevelSize: 0,
    bevelOffset: 0,
    bevelSegments: 1
  }
  const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings)
  const material = new THREE.MeshStandardMaterial({
    color,
    transparent: false,
  })
  const mesh = new THREE.Mesh( geometry, material )
  mesh.name = name
  mesh.position.y = height / 2
  mesh.rotateX(Math.PI / 2)
  const line = getBuildingLine(points, height, lineColor)


  // 绘制物体边线
	// const edges = new THREE.EdgesGeometry(geometry)
  // const edgesMaterial = new THREE.LineBasicMaterial({
	//   color: lineColor,
	// })
	// const line = new THREE.LineSegments(edges, edgesMaterial);
	mesh.add(line)
  return mesh
}

/**楼体线框 */
function getBuildingLine(points: [number, number][], height: number, lineColor: THREE.Color) {
  const pointsV3 = pointListToV3(points, true)
  const lineVerticalPoints = generatePoints(pointsV3, 2)
  /**水平线框数组 */
  const lineHorizontalPoints = [
    pointsV3,
    pointListToV3(points, true, 0.2),
    pointListToV3(points, true, 0.4),
    pointListToV3(points, true, height - 0.4),
    pointListToV3(points, true, height - 0.2),
    pointListToV3(points, true, height),
  ]
  const edgeVertices = new THREE.BufferGeometry()
  const vertices = []
  // 水平线
  for (let i = 0; i < lineHorizontalPoints.length; i++) {
    for (let k = 0; k < lineHorizontalPoints[i].length - 1; k++) {
      const pointA = lineHorizontalPoints[i][k]
      const pointB = lineHorizontalPoints[i][k + 1]
      vertices.push(pointA.x, pointA.y, pointA.z, pointB.x, pointB.y, pointB.z)
    }
  }
  // 垂直线
  for (let i = 0; i < lineVerticalPoints.length; i++) {
    const pointA = lineVerticalPoints[i]
    const pointB = new THREE.Vector3(lineVerticalPoints[i].x, height, lineVerticalPoints[i].z)
    vertices.push(pointA.x, pointA.y, pointA.z, pointB.x, pointB.y, pointB.z)
  }
  edgeVertices.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3))
  const edgesMaterial = new THREE.LineBasicMaterial({
	  color: lineColor,
	})
  const line = new THREE.LineSegments(edgeVertices, edgesMaterial)
  // 调整方向
  line.rotation.x = -Math.PI / 2
  // 调整位置
  line.position.z = height / 2
  return line
}

function parsePoints (array: number[][]): THREE.Vector2[] {
  // 形状坐标点，优化后的
  let shapePoints: THREE.Vector2[] = []
  for (let i = 0; i < array.length; i++) {
    let point = new THREE.Vector2(array[i][0], array[i][1])
    shapePoints.push(point)
  }
  return shapePoints
}

export default createBuilding